/*
 * Copyright 2007 Agile Plugins Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.agileplugins.settings;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class DirectorySync {
    private Logger logger = Logger.getInstance(getClass().getName());

    public void sync(File source, File dest) {
        if (!source.exists()) {
            throw new IllegalArgumentException("Source file " + source + " does not exist.");
        }
        File[] files = source.listFiles();
        File[] destFiles = new File[0];
        if (dest.exists() && dest.isDirectory()) {
            destFiles = dest.listFiles();
        }
        Map destFilesMap = new HashMap();
        for (int i = 0; i < destFiles.length; i++) {
            File file = destFiles[i];
            destFilesMap.put(file.getName(), file);
        }
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            File destFile = (File) destFilesMap.remove(file.getName());
            if (destFile == null) {
                copyFiles(file, dest);
            } else {
                if (file.isDirectory() && destFile.isDirectory()) {
                    sync(file, destFile);
                } else {
                    if (file.isFile() == destFile.isFile()) {
                        if (file.length() != destFile.length()) {
                            copyFiles(file, dest);
                        }
                    } else {
                        deleteFile(destFile);
                        copyFiles(file, dest);
                    }
                }
            }
        }
        for (Iterator iterator = destFilesMap.values().iterator(); iterator.hasNext();) {
            File file = (File) iterator.next();
            if (!file.getName().equals("CVS") && !file.getName().equals(".svn")) {
                deleteFile(file);
            }
        }
    }

    private void deleteFile(File destFile) {
        FileUtil.delete(destFile);
    }

    private void copyFiles(File source, File destDir) {
        try {
            File dest = new File(destDir, source.getName());
            if (source.isFile()) {
                FileUtil.copy(source, dest);
            } else {
                FileUtil.copyDir(source, dest);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
